package box.interview.wx.miniapp.controller;

import box.interview.wx.miniapp.config.ApplicationConfig;
import box.interview.wx.miniapp.controller.vo.LoginParam;
import box.interview.wx.miniapp.controller.vo.LoginResultData;
import box.interview.wx.miniapp.entity.WxMiniappCategory;
import box.interview.wx.miniapp.entity.WxMiniappInterview;
import box.interview.wx.miniapp.entity.WxMiniappLoginUser;
import box.interview.wx.miniapp.mapper.WxMiniappCategoryMapper;
import box.interview.wx.miniapp.mapper.WxMiniappLoginUserMapper;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 登录授权
 * 参考：https://blog.51cto.com/sihai/2145116
 */
@RestController
@RequestMapping(value = "/com/wx/authorize")
public class AuthorizeController {

    @Autowired
    private WxMaUserService wxMaUserService;

    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private ApplicationConfig applicationConfig;

    @Autowired
    private WxMiniappCategoryMapper wxMiniappCategoryMapper;

    @Autowired
    private WxMiniappLoginUserMapper wxMiniappLoginUserMapper;

    @PostMapping("login")
    public ResponseEntity login(@RequestBody LoginParam loginParam) {
        // 临时登录凭证code
        String code = loginParam.getCode();
        WxMaJscode2SessionResult session = null;
        try {
            // https://api.weixin.qq.com/sns/jscode2session
            session = wxMaUserService.getSessionInfo(code);
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        // 唯一ID
        String openid = session.getOpenid();

        // 私钥
        String sessionKey = session.getSessionKey();

        QueryWrapper<WxMiniappLoginUser> wrapper = new QueryWrapper<>();
        wrapper.eq("open_id", openid);
        WxMiniappLoginUser user = wxMiniappLoginUserMapper.selectOne(wrapper);
        if (user == null) {
            user = new WxMiniappLoginUser();
            user.setOpenId(openid);
            user.setSessionKey(sessionKey);
            user.setStatus(true);
            user.setCreateDate(LocalDateTime.now());
            user.setUpdateDate(LocalDateTime.now());
            wxMiniappLoginUserMapper.insert(user);
        }

        // 生产skey
        String skey = DigestUtils.md5DigestAsHex((openid + System.currentTimeMillis()).getBytes()).toUpperCase();

        // 缓存数据
        cacheRedis(openid, sessionKey, skey);

        LoginResultData data = new LoginResultData();
        data.setSkey(skey);
        return ResponseEntity.status(HttpStatus.OK).body(data);
    }

    /**
     * 缓存数据
     *
     * @param openid
     * @param sessionKey
     * @param skey
     */
    public void cacheRedis(String openid, String sessionKey, String skey) {

        String openid2skey = applicationConfig.openid2skey;
        String skey2openid = applicationConfig.skey2openid;
        String skey2sessionKey = applicationConfig.skey2sessionKey;

        // openid -> skey
        Object skeyObj = redisTemplate.opsForHash().get(openid2skey, openid);
        String sky = skeyObj == null ? null : skeyObj.toString();
        if (!StringUtils.isEmpty(sky)) {
            // 删除缓存
            redisTemplate.opsForHash().delete(openid2skey, openid);
            redisTemplate.opsForHash().delete(skey2openid, skey);
            redisTemplate.opsForHash().delete(skey2sessionKey, skey);
        }


        // openid -> skey
        redisTemplate.opsForHash().put(openid2skey, openid, skey);
        redisTemplate.expire(openid2skey, 5, TimeUnit.DAYS); //设置5天过期
        // skey -> openid
        redisTemplate.opsForHash().put(skey2openid, skey, openid);
        redisTemplate.expire(skey2openid, 5, TimeUnit.DAYS); //设置5天过期
        // skey -> sessionKey
        redisTemplate.opsForHash().put(skey2sessionKey, skey, sessionKey);
        redisTemplate.expire(skey2sessionKey, 5, TimeUnit.DAYS); //设置5天过期

    }

    @GetMapping("logout")
    public ResponseEntity logout(HttpServletRequest request) {
        String openid2skey = applicationConfig.openid2skey;
        String skey2openid = applicationConfig.skey2openid;
        String skey2sessionKey = applicationConfig.skey2sessionKey;

        String token = request.getHeader("token");
        Object obj = redisTemplate.opsForHash().get(skey2openid, token);
        if (obj != null) {
            String openid = (String) obj;
            redisTemplate.opsForHash().delete(openid2skey, openid);
        }
        redisTemplate.opsForHash().delete(skey2openid, token);
        redisTemplate.opsForHash().delete(skey2sessionKey, token);
        return ResponseEntity.status(HttpStatus.OK).body(null);
    }

}
